home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
uud
< prev
next >
Wrap
Internet Message Format
|
1995-03-31
|
18KB
From: Jan Brittenson <bson@rice-chex.ai.mit.edu>
Subject: v03i009: uud - a uudecoder v1.0b, Part01/01
Newsgroups: comp.sources.hp48
Followup-To: comp.sys.hp48
Approved: spell@seq.uncwil.edu
Checksum: 3800185134 (verify with brik -cv)
Submitted-by: Jan Brittenson <bson@rice-chex.ai.mit.edu>
Posting-number: Volume 3, Issue 9
Archive-name: uud/part01
BEGIN_DOC uud.doc
This is a beta version of UUD, an HP-48 uudecoder. It is considered
a test version since any bugs may have rather disastrous effects, and
although I've tried to test and debug it thoroughly, new problems may
surface under unusual conditions. This means that if losing any data
is unacceptible, then you should probably refrain from using this
program until some time has passed with no bug reports, at which point
I will repost it as a non-beta version.
UUD is relatively simple to use:
UUD
Uudecode the string in level one, replacing
it with the resulting object.
string --> obj
Any kermit preamble (the familiar "HPHP48-X" sequence) is ignored,
so it can be used to uudecode objects built on a development system
without bothering to generate the kermit preamble, as well as those in
binary HP-48 kermit format. Any preamble is simply skipped.
The total memory usage is the size of the string plus the size of
the resultant object, plus ten nybbles. Since the size of a uuencoded
file is about 1.6 times that of a binary file, the largest decodable
string is approximately the available memory divided by 2.6. For 24kB
of free memory, this means roughly 9.5kB. The string can reside
anywhere, while the result will be allocated in TEMPOB.
The binary and source code is provided "as is," under the GNU
General Public License. For more details on this, see the source code
included below. As I post this, I notice the code may need some
browsing, which I will take care of once any bugs are fixed.
Happy hacking!
-- Jan Brittenson
bson@ai.mit.edu
END_DOC
UUD
Size: 346 bytes
Xsum: #7f25h
uuencoded:
BYTES: #7F25h 353.5
BEGIN_UU uud.uue
begin 644 uud
M2%!(4#0X+5B=+2#[& U T-D"S"V@$0 "08._>0:H"!0#810D&/A(&/G0UC?D
M "XRA%&49J38F5G:6Z2&;(A,!2H ZWXTF> G>P& G<6!'XWD9;7+>K)AH&O
M&9#Z$ !7'A<>UQV7'5-(4$A2&:8A$)$8^/H!.80 $H< A!)0)G#6GI@:$?
MT:*>K*P8^A"%;5N/+WT&^"EE, 2L ZW8R6[ FV&BC/%=!2,RP,%A(S+ W )4
M 8 ?9 8!$'1^<10T086_>09!%U,Q$$9!AH&OA)$O?6%T5G ID)8?ZAF0 1QS
M,16P)P<W \6-/10%0:Y>8<%/%A,@:T$,$S_@%C#8IXQQ($ -8<%?\Y1^#E
M8<%?\W0=I!,-:0(PH9 F !#Z<&)P7G!:<%8@A!48^H'LM("A#X@4&&J1:DXQ
G&&J0:$$1%1 'P%$!<0 -#8WHN0)7^+4)LP]ZI$=G\N"&,"LQL!(#
end
END_UU
ASC encoded:
BEGIN_ASC uud.asc
%%HP: T(1)A(D)F(.);
"D9D202BF81D0040D9D20CCD20A1100201438FB97608A804130164142818F8481
9F0D6D734E00008BAC116415A93926567696E629912B1203418A30DA8F2D7608
D9CE6020776140E77319697DD2AE9C6818FA9109AF010075E171E17DD179D135
84058425916A120119818FAF10934800001082078014522076D0969E181AF11D
2AE9CACA81AF0158D6B5F8F2D7608F92560340CA30DA8D9CE60CB9162AC81FD5
5032230C1C1632230CCD20451008F14660100147E71741431458FB9760147135
130164146818FA4819F2D716476507920969F1AE910910C13713510B72707330
5CD8D3415014EAE5161CF4613102B614C031F30E61038D7AC8170204D0161CF5
3F49E7E00500161CF53F47D14A31D09620031A09620001AF072607E507A50765
02485181AF18CE4B081AF0884181A619A6E41381A6098614115101700C151017
00D0D0D88E9B20758F5B903BF0A74A74762F0E6803B2130B213052F7"
END_ASC
O /
\/
/\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O \
BEGIN_SRC uud.star
;; uud.star -- HP-48 uudecoder
;; UUD is not distributed by the Free Software Foundation. Do not
;; ask them for a copy or how to obtain new releases. Instead, send
;; e-mail to the address below. UUD is merely covered by the GNU
;; General Public License.
;;
;; Please send your comments, ideas, and bug reports to
;; Jan Brittenson <bson@gnu.ai.mit.edu>
;; Copyright (C) 1991 Jan Brittenson
;;
;; UUD is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 1, or (at your option)
;; any later version.
;;
;; UUD is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; This program is distributed without a copy of the GNU General
;; Public License; to obtain a copy, write to the Free Software
;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA, or send e-mail
;; to bson@gnu.ai.mit.edu.
;; UUD is written in STAR assembler. The command line below
;; exemplifies how to build it:
;;
;; star -j uud uud hp48 stdsyms uud
;;
;; The file hp48.star, which contains macro definitions specific to
;; the HP-48, is included with the STAR distribution, obtainable by
;; anonymous FTP from ftp.ai.mit.edu, in pub/star-1.04.4.tar.Z. The
;; file stdsyms.star is a file containing entry point definitions for
;; the HP-48, although UUD does not rely heavily on ROM calls.
;;
;; Jan Brittenson
;; Boston, 25 November 1991
; Bugs/problems
;
; The file name is not extracted from the uu string. It could be
; returned in level 1 with the result in level 2 for easy storage.
; How often is the file name of interest? I don't know, since there
; hasn't been a uudecoder for the HP-48 out there yet. Things should
; become more clear once UUD has been in use for a while.
radix 0x10
header `x'
;; UUD
;;
;; In:
;; 1: uu.string
;;
;; Out:
;; 1: result.any
rpl
Prg ; PRG
Switch_on_argtype ; Switch on argument type
Short_3 ; STR
Prg ; PRG
endrpl
; Verify string format and calculate resulting size.
;
; In:
; 1: uu.string
;
;
; Out (if valid string) (if invalid)
; 3: uu.string 2: uu.string
; 2: size.short 1: @#3a81
; 1: @#3ac0
;
code
; Get uu.string
clr p
move.a @d1, a
call save_regs ; Save system registers
brz.a a, $1077 ; End of stack - fail
; Verify string is at least 14 characters
move a, d0
add 5, d0 ; D0 = &string size
move.a @d0, a
sub.a 5, a
srb.a a
move.a a, c
move.a c, d ; D.A = string size, in bytes
move.p5 ^d14, c
brge.a c, a, $1077 ; Too short - ignore request
; Verify string starts with `begin'
add 5, d0 ; D0 = &line 1
move.10 @d0, a
move.p10 `begin', c
move 9, p
breq.wp c, a, $1001 ; Yup `begin' - sum up size
; Fail
$1077:
clr p
move.p5 true, c
move.a c, a
call restore_regs
jump pushobj_a_rplret ; Push @#3ac1 and continue
; D0 points to string data - sum up reulting string size. D.A contains
; the size of the remainer. R1.A holds the sum. Also decode the first
; 24 bits and see if they are `HPHP48-' - if so, adjust size by 16 nybbles.
$1001:
clr p
call next_record ; Advance to first line
brcs $1077 ; Uh... end of string?
call decode_char ; Decode record size
brz.b b, $1077 ; Null file - no can do, man!
clr.a c
move.b b, c ; C.A = record size
slb.a c ; In nybbles
sub.a ^d10, c ; Less 10
move c, r1 ; R1.A = first record size - 10
clr.w a
move a, r0 ; Assume no inhibition count
call uud_incrchar ; 6 bits
call uud_incrchar ; 12 bits
call uud_incrchar ; 18 bits
call uud_incrchar ; 24 bits
move.p6 `HPH', c ; Really only need to check first
; 3 bytes, since "HPH" is not a
; valid prologue.
move 5, p
brne.wp c, a, $1102 ; Nope preamble - ignore
clr p
move r1, c
sub.a ^d16, c ; Reduce size by 16
move c, r1
move.p5 ^d8, c ; Preamble size 8 bytes
move c, r0
$1102:
clr p
$1100:
call next_record ; Advance to next line
brcs $10770 ; Uh... end of string?
clr p
call decode_char ; B.B = uud(@D0+)
brz.b b, $1109 ; Last record - done
move.a r1, a ; A.A = sum
clr.a c
move.b b, c ; C.A = record size
add.a c, a ; A.A = new sum
add.a c, a ; ...in nybbles
move.a a, r1 ; R0.A = new sum
brcc $1100 ; Loop
$10770:
jump $1077
; Successful completion. Push size in R0.A, @#3ac0 and continue.
$1109:
call restore_regs ; Restore RPL registers
call pushshort_r0r1 ; Push preamble and result
; size as shorts
move.p5 false, c
move.a c, a
jump pushobj_a_rplret ; Push @#3ac0 and continue
endcode
; Allocate target
rpl
If_true_then
Error_bad_arg_value
Nullstring, Swap, Realloc, Swap
endrpl
; Decode object
;
; In:
; 3: uu.string
; 2: result.string (in TEMPOB)
; 1: preamble-size.short
;
; Out:
; 1: result.any
;
code
call getshort ; A.A = preamble size
move a, r0 ; R0.A = preamble size
move.a @d1, c ; C.A = &result area
inc.a d
add 5, d1
move.a @d1, a ; A.A = &uu.string
move.a c, @d1 ; Replace with result
call save_regs ; Save RPL registers
move.a @d1, c ; C.A = &result area
move c, d1 ; D1 = &result area
move a, d0 ; D0 = &uu.string
add 5, d0
move.a @d0, c ; C.A = uu.string size, in nybbles
sub.a 5, c
srb.a c ; (size-5)/2
move.a c, d ; D.A = uu.string size, in bytes
add 5, d0 ; Advance D0 to uu.string data
call next_record ; Advance D0 to next record
; Main uudecode loop. At this point:
;
; D0 = address of first record
; D1 = address of string object (to be overwritten)
; D.A= string character count
; R0.A= # of bytes of prologue to skip
uud_main:
call decode_char ; B.B = size (0-63) from @D0+
brz.b b, uud_finish ; Null record - done, skip rest
move.b b, c
move c, r1 ; R1.A = Store limit
move c, r4 ; R4.B = record byte count
swap c, d1
move c, d1
move c, r3 ; R3.A = original destination address
call decode_record ; Decode record, @D0+ --> @D1+
; Advance D0 to next record and loop
call next_record
brcc uud_main ; Decode next record
; We're done processing. Simply return, since the result object replaces
; the uu.string object.
uud_finish:
jump rr_rplcont
;;
;; Decode character.
;; In:
;; D0 = address of character
;; D.A= characters left in string
;;
;; Out:
;; B.B= 6-bit character code
;; D.A= decremented, exit if zero
;; Carry= clear
;;
;; Used:
;; C.B
;;
decode_char:
move.b @d0, c
move.b c, b ; B.B = next character
add 2, d0 ; Advance to next character
dec.a d
brcs uud_error ; Nothing left - error
move.p2 ` ', c ; Offset
sub.b c, b ; Subtract offset
brcs uud_error ; Unprintable - error
move.p2 077, c
and.b c, b ; Clear bits 6 and 7 of character
retclrc
; Error, bad string
uud_error:
jump Error_bad_arg_value+5
;;
;; Advance to beginning of next record. First advance to CR/LF,
;; then advance until non-CR/LF.
;; In:
;; D0 = character pointer
;; D.A= characters left in string
;;
;; Out:
;; D0 = address of first char of next record
;; D.A= characters left in string
;; Carry = clear
;;
;; Used:
;; C.B, A.B
;;
next_record:
$2:
call crlf_p ; Do we have CR or LF?
brcs $1 ; Yes - go skip CR and LFs
add 2, d0 ; Advance to next char
dec.a d ; One char less in string
brcc $2
brcs uud_error ; Premature end of string
$1:
call crlf_p ; Do we have CR or LF?
retcc ; No - return
add 2, d0 ; Skip it
dec.a d ; One char less in string
brcc $1
brcs uud_error ; Premature end of string
; Test if character @D0 is CR or LF
crlf_p:
move.b @d0, a
move.p2 CR, c
reteq.b c, a ; Return with carry set if CR
move.p2 LF, c
reteq.b c, a ; Return with carry set if LF
ret ; Otherwise, return with carry clear
;;
;; Decode record.
;; In:
;; D0 = address of first char in record
;; D1 = address of destination byte buffer
;; D.A = number of characters left in string
;; R0.A= number of bytes of prologue to skip
;; R1.A= number of bytes to really decode
;;
;; Out:
;; D0 = address of first char following record (CR/LF)
;; D1 = address of first byte following the last one added (including
;; pad bytes)
;; D.A = number of characters left in string, adjusted
;; Carry = clear
;;
;; Used:
;; A, B, C
;;
decode_record:
clr.w a
call uud_incrchar ; 6 bits
call uud_incrchar ; 12 bits
call uud_incrchar ; 18 bits
call uud_incrchar ; 24 bits
; At this point, the 3 bytes are in A.6, in reverse order, i.e.
; the third byte is in A.B.
move 4, p ; Nybbles 4,5 is byte 1
$1:
setb 1, st
move.a r0, c
dec.a c ; One less preamble byte to go
brcs $101
move.a c, r0
clrb 1, st
$101:
move.b r1, c
dec.b c ; One less byte to copy
brcs $171 ; End of copy - return
move.b c, r1
brbc 1, st, $71
$102:
move.p a, @d1 ; Add low nybble of byte
inc d1
inc p
move.p a, @d1 ; Add high nybble of byte
inc d1
dec p ; Move P to low nyb of next byte
$71:
dec p
dec p
brne p, ^d14, $1 ; Loop bytes until P wraps
clr p
call crlf_p ; CR or LF?
brcc decode_record ; No - decode another 24 bits
$171:
retclrc
; Add 6 bits of uu-encoded data to the 6 low-order bits of A.W
uud_incrchar:
sln.w a ; Shift A left 6 bits
slb.w a
slb.w a
call decode_char ; Get 6 bits of data in B.B
or.b b, a ; Add to A
retclrc
even
endcode
; Tail end of RPL program object
rpl
EndObj ; PRG
EndObj ; PRG
endrpl
END_SRC
O /
\/
/\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O \
BEGIN_SRC stdsyms.star
;; stdsyms.star -- Common Symbols
;;
;; This file is in the public domain. Please notice that
;; uud.star is not.
;;
;; Jan Brittenson
;; Boston, 25 November 1991
;;
nlistblock
radix 0x10
GROB_null = 505b2
OpenIO = 2eb37
CloseIO = 315c6
Freeze = 142fb
Cllcd = 5046a
Eval_prev_context = 6fd1
Push_next = 6e97
Char_000 = 6541e
Add_string_char = 52ee
Add5 = 6258a
Inc = 3def
Dup_Inc = 628eb
Short_200h = 64f0e
Short_100h = 64e32
Short_60h = 64c8e
Short_c0h = 64dd8
Short_bbh = 64dce
Short_31h = 64b44
String_to_grob_pitch8 = 11d00
Nullstring = 55df
Nullstring_copy = 1613f
Program_null = 40788
Realloc = 61c1c
Num = 1410f
Add = 3dbc
Add_string_string = 5193
LeftLess1_string_short = 63259
ArrayTo_array = 1d0ab
ArrayTo = 1d0ab
Dec = 3e0e
Dup = 3188
EndObj = 312b
Equalp = 3d19
Nonzerop = 3cc7
No_args = 18a15
Zerop = 3ca6
Dup_Zerop = 62266
Get_2Lastlocal = 613e7
Get_3lastlocal = 6140e
Get_4lastlocal = 61438
Get_lastlocal = 613b6
If_then_else = 61ad8
If_true_then = 619bc
If_not_true_then = 712a
;If_true_then = 619ad
Dup_If_zero_then_exec = 618a8
If_User_flag_then_else = 63ed9
Pview_short_short = 4f052
Listob = 2a74
ListAlgPrgTo = 54af
ListTo = 54af
ListTo_StoreLocals = 74d0
Local_M = 0xe4c1
Local_N = 0xe4ae
Local_S = 41bea
Mul = 3ec2
Mul2 = 3e6f
Mul_array_real = 362dc
Next = 7334
Prg = 2d9d
True = 3a81
False = 3ac0
Bin_to_short = 5a03
Two_Bins_to_shorts = 4f3d1
Real_to_short = 18cea
Real_to_short_Swap = 62e7b
Swap_Over = 61380
Roll = 3325
Drop = 3244
Swap_Drop = 60f9b
Drop2 = 3258
Xlib_to_Rpl = 7e99
Error_Bad_arg_type = 18cb2
Short_0bh = 405d
Clear_lastargs = 4d33
Reset_lastargs = 53842
Need_2_args = 18a8d
Need_4_args = 18b9f
SL_Need_1_arg = 18aa5
Switch_on_argtype = 18fb2
SL_Switch_2_argtypes = 18edf
SL_Switch_on_argtype = 18ece
SL_Switch_4_argtypes = 18f01
SaveLast_Need_1_arg = 18aa5
Lastkey = 4714
Short_0 = 3fef
Short_1 = 3ff9
Short_2 = 4003
Short_3 = 400d
Short_4 = 4017
Short_5 = 4021
Short_8 = 403f
Short_0dh = 4071
Short_0fh = 4085
Short_10h = 408f
Short_16h = 40cb
Short_1fh = 4125
Short_20h = 412f
Short_21h = 4139
Short_40h = 64bda
Short_7fh = 1cd16
Short_83h = 64d24
Pdim = 4b323
Equal2p = 6229a
Real_1 = 2a2c9
Real_2 = 2a2de
Real_3 = 2a2f3
Real_4 = 2a308
Real_5 = 2a31d
Real_7 = 2a347
Short_to_real = 18dbf
Start_1_to_N = 73db
Store_2lastlocal = 615f0
Store_3lastlocal = 61600
Store_4lastlocal = 61610
Store_lastlocal = 615e0
Store_local = 61625
Swap = 3223
Array_dims = 35a9
ToArray_real = 1d02c
ToArray_list = 1d040
Size_list = 567b
ToList = 5459
ToList2 = 631b9
TwoShorts_to_reals = 1950b
TwoReals_to_shorts = 194f7
Short_to_bin = 59cc
Swap_Over = 61380
Over = 32c2
Rot = 3295
Rolld3 = 60fac
Rolld4 = 6109e
Div2 = 3e8e
Div = 3ef7
Disp_any_real = 140ab
Disp_pitch8Str_line0 = 1245b
Disp_pitch8Str_line1 = 1246b
Disp_pitch8str_line2 = 1247b
Disp_pitch8str_line3 = 1248b
Disp_pitch8str_line4 = 1249b
Disp_pitch8str_line5 = 124ab
Disp_pitch8str_line6 = 124bb
Disp_pitch8str_line7 = 124cb
Loop = 71a2
Exit_loop = 71e5
Until = 71c8
Next = 7334
If_ATTN_then_FlushKbd_Kill = 4243e
If_ATTN_then_End = 4245c
Pr1 = 318fe
Error_bad_arg_value = 18ca2
If_not_equal_then_short = 6336c
;; ML routines
getshort = 6641
get2shorts = 3f5d
pushshort_r0r1 = 6529
pushshort_r0 = 6537
pushshort_r0_rplret= 18d0a
pushobj_a = 54266
pushobj_a_rplret = 6ec9
stralloc_nibbles = 5b7d
blkcopy = 670c
save_regs = 679b
restore_regs = 67d2
rplcont = 71be
rr_rplcont = 5143
kbflush = 0xd57
keybuf = 704ea
indicate_not_busy = 42359
int_mask = 10e
uart_xmit = 116
adjust_parity = 3113d
uart_xmit_rdy_p = 310ca
recv_getc = 31289
ATTN_p = 4988
clear_ATTN = 0xd8e
graph_grob_ptr = 70565
stack_grob_ptr = 70556
Copyright = ch^^d169
Beta = ch^^d223
CR = ch^015
LF = ch^012
END_SRC
-- Jan Brittenson
bson@ai.mit.edu